# -*- coding: utf-8 -*-
class SaleReturnedController < ApplicationController
  before_filter :employee_authorize,:except=>[:sale_returned_print_header,:sale_returned_print_footer,:sale_returned_print_content]
  before_filter :sys_before_log
  before_filter :employee_action_hx,:except=>[:sale_returned_print_header,:sale_returned_print_footer,:sale_returned_print_content]
  before_filter :privilege_filter ,:except=>[:newSaleReturned,:editSaleReturned,:associateAuditSaleReturned,:sale_returned_print_header,:sale_returned_print_footer,:sale_returned_print_content,:entryConfirm]

  #显示新添加销售退货订单页面
  def newSaleReturned

  end

  #显示编辑销售退货订单页面
  def editSaleReturned

  end

  #显示销售退货订单列表页面
  def saleReturnedList
  end

  #显示内勤审批页面
  def associateAuditSaleReturned

  end

  #显示供仓库使用的销售订单退货列表
  def saleReturnedListForEntry

  end
  
  #生成新的销售退货订单
  def create
    
    paramsHash = Util.paramsPreprocessToHash(params[:data])
    #productHash = paramsHash["products"][0]

    saleReturned = SaleReturned.new
    saleReturned.company_id = session[:company_id]
    saleReturned.department_id = session[:department_id]
    saleReturned.employee_id = session[:employee_id]
    saleReturned.sale_order_id = paramsHash['sale_order_id']
    #记录vendorId是为了查询方便。
    saleReturned.customer_id = SaleOrder.find(saleReturned.sale_order_id).customer.id
    saleReturned.linkman = paramsHash['linkman']
    saleReturned.phone = paramsHash['phone']
    saleReturned.receive_address = paramsHash['delivery_address']
    #saleReturned.tax_rate = paramsHash['tax_rate']
    saleReturned.return_date = paramsHash['return_date']
    saleReturned.description = paramsHash['description']
    saleReturned.auditing_status = Constants::AUDIT_APPLY_RETURN
    #插入products信息
    productsHashArray = paramsHash["products"]
    productsHashArray.each do |productHash|
      #只有当用户选择的产品不为空时，才有详细订单。
      if productHash["product_id"] !=""
        saleReturnedDetail = SaleReturnedDetail.new
        saleReturnedDetail.product_id = productHash["product_id"]
        saleReturnedDetail.quantity = productHash["quantity"]
        saleReturnedDetail.unit_price = productHash["unit_price"]
        saleReturnedDetail.discount = productHash["discount"]
        saleReturnedDetail.amount = productHash["amount"]
        saleReturned.amount = saleReturned.amount + saleReturnedDetail.amount #计算订单总金额
        saleReturnedDetail.description = productHash["description"]
        saleReturned.sale_returned_details << saleReturnedDetail
      end
    end
    #saleReturned.save

    #开始事务，确保在流水号正常的情况下，保存销售退货订单,一但出现问题，则循环执行
    begin
      Sequence.transaction do
        #开始为销售退货订单取得流水号
        sequence = Sequence.where("company_id = ? AND sub_type = ?",session[:company_id],SaleReturned.name).first

        sequence.seq_no = sequence.seq_no + 1
        saleReturned.seq_number = sequence.seq_no
        saleReturned.order_number = sequence.ab + ":" + saleReturned.seq_number.to_s + ":" + Date.today.to_s
        sequence.save!
        saleReturned.save!
      end
    rescue ActiveRecord::StaleObjectError
      #这个异常是说明，你当提交时，有人提前更新了你之前读取的信息，违反乐观锁。要retry
      #这里特别指序号产生表。
      logger.info "somebody using sn before yours.............................................................."
      DbLog.info(session[:company_id], session[:department_id], session[:employee_id], params[:controller], params[:action], request.remote_ip ,"StaleObjectError")
      retry
    rescue ActiveRecord::RecordNotFound
      logger.info "RecordNotFound................................................................................"
      DbLog.info(session[:company_id], session[:department_id], session[:employee_id], params[:controller], params[:action], request.remote_ip ,"RecordNotFound")
    rescue Exception => e
      logger.info "logging......................................................................................."
      DbLog.info(session[:company_id], session[:department_id], session[:employee_id], params[:controller], params[:action], request.remote_ip ,e.to_s)
      logger.info e
    end

    info="成功"
    result = "{success:true,info:'#{info}'}"
    render :text=>result, :layout=>false
  end

  #更新销售退货订单
  def update
    
    paramsHash = Util.paramsPreprocessToHash(params[:data])
    #productHash = paramsHash["products"][0]
    saleReturned = SaleReturned.where("id = ? AND company_id = ? AND is_locked <> 1 AND auditing_status <> ?",paramsHash['id'],session[:company_id],'通过').first
    if saleReturned != nil
      if saleReturned.lock_version > paramsHash['lock_version'].to_i
        info="有其它用户在您保存之前编辑过此销售退货订单记录，请从新编辑！"
        result = "{success:true,info:'#{info}'}"
        render :text=>result, :layout=>false and return false
      end
      saleReturned.company_id = session[:company_id]
      saleReturned.department_id = session[:department_id]
      saleReturned.employee_id = session[:employee_id]
      saleReturned.linkman = paramsHash['linkman']
      saleReturned.phone = paramsHash['phone']
      saleReturned.receive_address = paramsHash['receive_address']
      saleReturned.return_date = paramsHash['return_date']
      saleReturned.description = paramsHash['description']
      saleReturned.auditing_status = Constants::AUDIT_APPLY_RETURN

      #products信息
      productsHashArray = paramsHash["products"]
      #在这里，要作一个增，删，编辑操作，以前台数据为准。
      #首先各取出前台与后台的ID数组
      fgIdArray = Array.new
      productsHashArray.each do |productHash|
        fgIdArray << productHash["id"].to_i
      end

      bgIdArray = Array.new
      saleReturnedDetails = saleReturned.sale_returned_details
      saleReturnedDetails.each do |saleReturnedDetail|
        bgIdArray << saleReturnedDetail.id
      end

      idIntersectionArray = fgIdArray & bgIdArray
      addIdArray = fgIdArray - idIntersectionArray
      delIdArray = bgIdArray - idIntersectionArray
      SaleReturnedDetail.delete(delIdArray)

      #在进行从新整理数据之前，先把采购订单的总金额置“0”
      saleReturned.amount = 0
      productsHashArray.each do |productHash|
        #只有当用户选择的产品不为空时，才有详细订单。
        if productHash["product_id"] !=""
          #没Id说明是新增加的。
          if productHash["id"] == ""
            saleReturnedDetail = SaleReturnedDetail.new
          else
            saleReturnedDetail = SaleReturnedDetail.find(productHash["id"].to_i)
          end
          saleReturnedDetail.product_id = productHash["product_id"]
          saleReturnedDetail.quantity = productHash["quantity"]
          saleReturnedDetail.discount = productHash["discount"]
          saleReturnedDetail.unit_price = productHash["unit_price"]
          saleReturnedDetail.amount = productHash["amount"]
          saleReturned.amount = saleReturned.amount + saleReturnedDetail.amount #计算订单总金额
          saleReturnedDetail.description = productHash["description"]
          saleReturned.sale_returned_details << saleReturnedDetail
        end
      end
      saleReturned.save!
    end

    info="成功"
    result = "{success:true,info:'#{info}'}"
    render :text=>result, :layout=>false    
  end

  #得到所有销售退货订单
  def getAllSaleReturneds
    begin
      conditionsHash = Hash.new
      paramsHash = Hash.new
      paramsHash[:offset] = params[:start].to_i
      paramsHash[:limit] = params[:limit].to_i
      conditionsStr = ''

      if params[:order_number].to_s != ''
        if conditionsStr == ''
          conditionsStr = 'sale_returneds.seq_number in (:order_number)'
        else
          conditionsStr = conditionsStr+' AND sale_returneds.seq_number in (:order_number)'
        end
        conditionsHash[:order_number] = params[:order_number].split(/,/)
      end

      #查询时增加了为仓库，为所有功能，如果为仓库，只查审批完成和撤消二种状态的订单
      searchType = params[:search_type]

      if searchType == "warehouse"
        if conditionsStr == ''
          conditionsStr = "sale_returneds.auditing_status != :auditing_status_1 AND sale_returneds.auditing_status != :auditing_status_2"
        else
          conditionsStr = conditionsStr+" AND sale_returneds.auditing_status != :auditing_status_1 AND sale_returneds.auditing_status != :auditing_status_2"
        end
        conditionsHash[:auditing_status_1] = '申请'
        conditionsHash[:auditing_status_2] = '审批退回'
      else
        if params[:auditing_status].to_s != '' && params[:auditing_status] != ' '
          if conditionsStr == ''
            conditionsStr = 'sale_returneds.auditing_status like :auditing_status'
          else
            conditionsStr = conditionsStr+' AND sale_returneds.auditing_status like :auditing_status'
          end
          conditionsHash[:auditing_status] = '%'+params[:auditing_status].to_s+'%'
        elsif params[:auditing_status] == ' '
          if conditionsStr == ''
            conditionsStr = 'sale_returneds.auditing_status = :auditing_status'
          else
            conditionsStr = conditionsStr+' AND sale_returneds.auditing_status = :auditing_status'
          end
          conditionsHash[:auditing_status] = ''
        end
      end


      if params[:customer_id].to_s != ''
        if conditionsStr == ''
          conditionsStr = 'customer_id = :customer_id'
        else
          conditionsStr = conditionsStr+' AND customer_id = :customer_id'
        end
        conditionsHash[:customer_id] = params[:customer_id].to_i
      end
      
      if params[:product_id].to_s != ''
        if conditionsStr == ''
          conditionsStr = 'sale_returned_details.product_id = :product_id'
        else
          conditionsStr = conditionsStr+' AND sale_returned_details.product_id = :product_id'
        end
        conditionsHash[:product_id] = params[:product_id].to_i
      end

      if params[:begin_date].to_s != ''
        if conditionsStr == ''
          conditionsStr = 'sale_returneds.action_date >= :begin_date'
        else
          conditionsStr = conditionsStr+' AND sale_returneds.action_date >= :begin_date'
        end
        conditionsHash[:begin_date] = params[:begin_date].to_date
      end

      if params[:end_date].to_s != ''
        if conditionsStr == ''
          conditionsStr = 'sale_returneds.action_date <= :end_date'
        else
          conditionsStr = conditionsStr+' AND sale_returneds.action_date <= :end_date'
        end
        conditionsHash[:end_date] = params[:end_date].to_date
      end
      role = Role.find(session[:role_id])
      if role.cross_company == "否"
        if conditionsStr == ''
          conditionsStr = 'sale_returneds.company_id = :company_id'
        else
          conditionsStr = conditionsStr+' AND sale_returneds.company_id = :company_id'
        end
        conditionsHash[:company_id] = session[:company_id]
      end
      count = SaleReturned.countAllReturnedSales conditionsStr,conditionsHash
      saleReturneds = SaleReturned.findAllReturnedSales conditionsStr,conditionsHash,paramsHash
      #jsonStr="{totalProperty:"+count.to_s+",root:"+saleReturneds.to_json(:include=>[:employee,:department,:customer,:associate_auditor,:warehouse_employee,:sale_order])+"}"
      jsonStr="{totalProperty:"+count.to_s+",root:"+saleReturneds.to_json(:include=>{:company=>{:only=>[:id,:name]},:employee=>{:only=>[:id,:name]},:warehouse=>{:only=>[:id,:name]},:department=>{:only=>[:id,:name]},:warehouse_employee=>{:only=>[:id,:name]},:customer=>{:only=>[:id,:name]},:associate_auditor=>{:only=>[:id,:name]},:sale_order=>{:include=>[:sales_strategy,:sale_type]}})+"}"
      #logger.info jsonStr
      render :text=>jsonStr, :layout=>false
    rescue Exception => e
      logger.info e
      DbLog.info(session[:company_id], session[:department_id], session[:employee_id], params[:controller], params[:action], request.remote_ip ,e.to_s)
    end
  end

  #得到某一个销售退货订单
  def getSaleReturnedsBySaleOrderId
    saleReturneds = SaleReturned.where("sale_order_id = ?",params[:sale_order_id])
    jsonStr="{totalProperty:"+saleReturneds.length.to_s+",root:"+saleReturneds.to_json(:include=>[:employee,:department,:customer,:associate_auditor,:warehouse_employee])+"}"
    render :text=>jsonStr, :layout=>false
  end
  
  #得到某一个销售退货订单
  def getSaleReturnedById
    saleReturned = SaleReturned.find(params[:id])
    rootStr = saleReturned.to_json(:include=>[:customer,:sale_order])
    jsonStr = "{root:["+rootStr+"]}"
    render :text=>jsonStr, :layout=>false
  end

  #根据某个销售退货订单Id得到详细信息
  def getSaleReturnedDetailsById
    saleReturnedDetails = SaleReturnedDetail.where(sale_returned_id:params[:sale_returned_id])
    jsonStr="{totalProperty:"+saleReturnedDetails.length.to_s+",root:"+saleReturnedDetails.to_json(:include=>{:product=>{:only=>[:id,:name,:number,:unit,:is_suit,:spec]}})+"}"
    #logger.info jsonStr
    render :text=>jsonStr, :layout=>false
  end

  #内勤审批
  def updateAuditingStatusByAssociate
    saleReturned = SaleReturned.find(params[:sale_returned_id])
    info = nil
    if saleReturned !=nil
      auditingStatus = params[:auditing_status]
      if(auditingStatus == "是")
        auditingStatus = Constants::PASS_APPLY_RETURN
      else
        auditingStatus = Constants::REJECT_APPLY_RETURN
      end
      saleReturned.auditing_status = auditingStatus
      saleReturned.associate_auditor_id = session[:employee_id]
      saleReturned.associate_audit_opinion =  params[:associate_audit_opinion]
      saleReturned.save!
      info = "成功"
    else
      info = "失败"
    end
    result = "{success:true,info:'#{info}'}"
    render :text=>result, :layout=>false
  end

  #销售退货入库完毕
  def entryFinish
    begin
      saleReturned = SaleReturned.find(params[:sale_returned_id])
      #对于已经入库的不能再次放库
      if saleReturned !=nil && saleReturned.store_status != Constants::FINISH_ENTRY
        saleReturned.warehouse_employee_id =  session[:employee_id]
        saleReturned.warehouse_id =  params[:warehouse_id]
        saleReturned.store_status = Constants::FINISH_ENTRY
        saleReturned.action_date = params[:action_date]
        saleReturnedDetails = saleReturned.sale_returned_details
        saleReturnedDetails.each do |saleReturnedDetail|
          #然后正式拆分此拆分单到结算表中。结算的方式就是主表是负数，然后拆分出来的产品是正数。
          productCollection = ProductCollection.new
          productCollection.company_id = saleReturned.company_id
          productCollection.department_id = saleReturned.department_id
          productCollection.employee_id = saleReturned.employee_id
          productCollection.customer_id = saleReturned.customer_id
          productCollection.warehouse_id = params[:warehouse_id]
          productCollection.action_date = params[:action_date]
          productCollection.product_id = saleReturnedDetail.product_id
          productCollection.quantity = saleReturnedDetail.quantity
          productCollection.description =  saleReturnedDetail.description
          productCollection.unit_price = saleReturnedDetail.unit_price
          productCollection.unit_amount = saleReturnedDetail.amount
          productCollection.amount = saleReturned.amount
          productCollection.resource_id =  saleReturned.id
          productCollection.resource_type =  SaleReturned.name
          productCollection.save!
        end

        saleReturned.save!
        #结算表处理完毕。
        info = "成功"
      else
        info = "失败"
      end
      result = "{success:true,info:'#{info}'}"
      render :text=>result, :layout=>false
    rescue Exception => e
      logger.info e
      DbLog.info(session[:company_id], session[:department_id], session[:employee_id], params[:controller], params[:action], request.remote_ip ,e.to_s)
    end
  end

  #销售退货订单的撤销
  def applyToCancel
    begin
      saleReturned = SaleReturned.find(params[:id])
      sysParam =  SysParam.find_by_company_id(session[:company_id])
      if sysParam.audit_for_sale_returned_cancel == "否"
        saleReturned.auditing_status = Constants::PASS_APPLY_CANCEL
        saleReturned.deal_with_status = Constants::CANCELED
        ProductCollection.delete_all("resource_type = 'SaleReturned' AND resource_id = #{params[:id]}")
        #如果不需要审批，则把汇总表中的数据设置为is_locked = 1
      else
        saleReturned.auditing_status = Constants::AUDIT_APPLY_CANCEL
      end
      saleReturned.associate_auditor_id = session[:employee_id]
      saleReturned.save!
    rescue Exception => e
      info = e.to_s
      logger.info info
      DbLog.info(session[:company_id], session[:department_id], session[:employee_id], params[:controller], params[:action], request.remote_ip ,e.to_s)
    end
    info = "成功"
    result = "{success:true,info:'#{info}'}"
    render :text=>result, :layout=>false
  end

  #对于一张销售订单，计算出当前还可以退货的数量和种类
  def getSaleOrderDetailsByIdForReturned
    saleOrderId = params[:sale_order_id]
    saleOrderDetails = SaleOrderDetail.select("sd.id,p.id as product_id,p.name as product_name,p.is_suit,sd.unit_price,p.number,p.spec,p.unit,sd.description,newrd.quantity as rd_quantity,(sum(sd.quantity) - ifnull(newrd.quantity,0)) as balance_quantity,(sd.amount/sd.quantity)*(sum(sd.quantity) - ifnull(newrd.quantity,0)) as amount,sd.discount ").joins("sd
left join (select rd.product_id,sum(rd.quantity) as quantity
from sale_returned_details rd left join sale_returneds r on r.id = rd.sale_returned_id
where r.sale_order_id = "+saleOrderId+" AND r.auditing_status != '#{Constants::PASS_APPLY_CANCEL}'
group by product_id) newrd on newrd.product_id = sd.product_id
left join products p on p.id = sd.product_id
where sd.sale_order_id =  "+saleOrderId+ " group by sd.product_id having sum(sd.quantity) - ifnull(newrd.quantity,0) > 0")

    jsonStr="{totalProperty:"+saleOrderDetails.length.to_s+",root:"+saleOrderDetails.to_json()+"}"
    #logger.info jsonStr
    render :text=>jsonStr, :layout=>false
  end

  #生成打印销售凭证的头部
  def sale_returned_print_header
    @saleReturned = SaleReturned.find(params[:id],:include=>[:warehouse,:sale_order,:customer])
    @saleOrder = @saleReturned.sale_order
    @companyName = SysParam.find_by_company_id(@saleReturned.company_id).company_name
  end

  #生成打印销售凭证的内容
  def sale_returned_print_content
    @saleReturned = SaleReturned.find(params[:id],:include=>[:sale_returned_details,:sale_order,:customer,:warehouse])
    @saleReturnedDetails = @saleReturned.sale_returned_details
    #在这儿，要根据销售出库订单的销售ID与产品ID，从新取出销售明细表中的相关产品价格和折扣以及数量金额。
    @totalQuantity = @saleReturnedDetails.sum(:quantity)
    logger.info @totalQuantity
  end

  def sale_returned_print_footer
    @saleReturned = SaleReturned.find(params[:id],:include=>[:sale_returned_details,:sale_order,:customer,:warehouse])
  end
  
  #返货取消.
  def cancelEntry
    begin
      saleReturned = SaleReturned.find(params[:id])
      sysParam =  SysParam.find_by_company_id(session[:company_id])
      saleReturned.store_status = ""
      ProductCollection.delete_all("resource_type = 'SaleReturned' AND resource_id = #{params[:id]}")
      saleReturned.warehouse_employee_id = session[:employee_id]
      saleReturned.save!
    rescue Exception => e
      info = e.to_s
      logger.info info
      DbLog.info(session[:company_id], session[:department_id], session[:employee_id], params[:controller], params[:action], request.remote_ip ,e.to_s)
    end
    info = "成功"
    result = "{success:true,info:'#{info}'}"
    render :text=>result, :layout=>false
  end
end
